(function (exports) {

    var TouchUtils = {
        effects: {
            NONE: "NONE"
            , SEPIA: "SEPIA"
            , ZOOM: "ZOOM"
        },
        isTouchMe: function (target, touch, event, deltaSize, rect) {
            deltaSize = deltaSize || cc.size(0, 0);

            //Get the position of the current point relative to the button
            var locationInNode = target.convertToNodeSpace(touch.getLocation());
            var s = target.getContentSize();
            var rect = rect || cc.rect(-deltaSize.width / 2, -deltaSize.height / 2, s.width + deltaSize.width, s.height + deltaSize.height);

            if(target.touchRect){//设置触摸区域
                rect = target.touchRect;
            }

            //Check the click area
            if (cc.rectContainsPoint(rect, locationInNode)) {
                var flag = true;
                var t = target;
                while (true) {
                    if (t == null)
                        break;
                    if (!t.isVisible() || t.getOpacity() == 0) {
                        flag = false;
                        break;
                    }
                    t = t.getParent();
                }
                return !!flag;
            }
            return false;
        },
        //设置不能点击
        setClickDisable: function(node, disable){
            node.disable = disable;
        },
        setTouchRect:function(node, rect){
            node.touchRect = rect;
        },
        _setOnTouchListener: function (node, options) {
            //if (!node)
            //    return;

            if (typeof options['swallowTouches'] === 'undefined')
                options['swallowTouches'] = true;

            if (!node.getUserData())
                node.setUserData({});
            var userData = node.getUserData();

            if (userData.listener)
                cc.eventManager.removeListener(userData.listener);

            var delta = 0;
            var deltaSize = cc.size(delta, delta);

            var sepiaVal = 0.7;

            var zoomDuration = 0.2;
            var zoomVal = 1.06 * (node.getScaleX() || 1);
            var zoomEnd = 1 * (node.getScaleX() || 1);

            var isStillInside = false;

            var beginPos = 0;
            var endPos = 0;

            var MAX_TOUCH_MOVE = 6.0;

            userData.listener = cc.EventListener.create({
                event: cc.EventListener.TOUCH_ONE_BY_ONE,
                swallowTouches: options['swallowTouches'],
                onTouchBegan: function (touch, event) {
                    if(node.disable){
                        return false;
                    }
                    beginPos = touch.getLocation();
                    if (TouchUtils.isTouchMe(node, touch, event, deltaSize)) {
                        if (options.effect === TouchUtils.effects.SEPIA)
                            Filter.sepia(node, sepiaVal);
                        else if (options.effect === TouchUtils.effects.ZOOM)
                            node.runAction(cc.scaleTo(zoomDuration, zoomVal, zoomVal));
                        if (options.onTouchBegan)
                            options.onTouchBegan(node, touch, event);
                        isStillInside = true;
                        playEffect(_.isUndefined(options['sound']) ? 'sound_clickBtn' : options['sound']);
                        return true;
                    }
                    return false;
                },
                onTouchMoved: function (touch, event) {
                    if (options.onTouchMoved && options.onTouchMoved(node, touch, event))
                        return true;
                    var ret = TouchUtils.isTouchMe(node, touch, event, deltaSize);
                    if (ret && !isStillInside) {
                        if (options.effect === TouchUtils.effects.SEPIA)
                            Filter.sepia(node, sepiaVal);
                        else if (options.effect === TouchUtils.effects.ZOOM)
                            addAction(node, cc.scaleTo(zoomDuration, zoomVal, zoomVal));
                        isStillInside = true;
                        if (options.onTouchMoveIn)
                            options.onTouchMoveIn(node, touch, event);
                    }
                    else if (!ret && isStillInside) {
                        if (options.effect === TouchUtils.effects.SEPIA)
                            Filter.remove(node);
                        else if (options.effect === TouchUtils.effects.ZOOM)
                            addAction(node, cc.scaleTo(zoomDuration, zoomEnd, zoomEnd));
                        isStillInside = false;
                        if (options.onTouchMoveOut)
                            options.onTouchMoveOut(node, touch, event);
                    }
                },
                onTouchEnded: function (touch, event) {
                    endPos = touch.getLocation();
                    if (options.isScroll && cc.pDistance(endPos, beginPos) > MAX_TOUCH_MOVE) {
                        Filter.remove(node);
                        return;
                    }
                    if (options.onTouchEndedWithoutCheckTouchMe)
                        options.onTouchEndedWithoutCheckTouchMe(node, touch, event);
                    if (TouchUtils.isTouchMe(node, touch, event, deltaSize)) {
                        if (options.effect === TouchUtils.effects.SEPIA)
                            Filter.remove(node);
                        else if (options.effect === TouchUtils.effects.ZOOM)
                            addAction(node, cc.scaleTo(zoomDuration, zoomEnd, zoomEnd));
                        if (options.onTouchEnded)
                            options.onTouchEnded(node, touch, event);
                        return true;
                    }
                    return false;
                }
            });

            cc.eventManager.addListener(userData.listener, node);
        },
        setOnclickListener: function (node, cb, options) {
            TouchUtils._setOnTouchListener(node, _.extend({
                effect: TouchUtils.effects.SEPIA
                , onTouchEnded: cb
            }, options || {}));
        },
        setOntouchListener: function (node, cb, options) {
            TouchUtils._setOnTouchListener(node, _.extend({
                effect: TouchUtils.effects.SEPIA
                , onTouchBegan: cb
            }, options || {}));
        },
        setListeners: function (node, options) {
            TouchUtils._setOnTouchListener(node, _.extend({
                effect: TouchUtils.effects.NONE
            }, options || {}));
        },
        removeListeners: function (node) {
            var userData = node.getUserData() || {};
            if (userData.listener) {
                cc.eventManager.removeListener(userData.listener);
                delete userData.listener;
            }
        }
    };

    exports.TouchUtils = TouchUtils;

})(window);